﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

namespace Teein.Proxy.Bot.Helper
{
    public class HttpRequestHelper
    {
        private static Dictionary<string, Encoding> RequestEncoding = new Dictionary<string, Encoding>();
        private Encoding defaultEncoding;

        private WebProxy m_proxy;
        /// <summary>
        /// 当前的HttpWebRequest对象
        /// </summary>
        public HttpWebRequest hwr { get; set; }

        public HttpRequestHelper()
        {

        }


        public HttpRequestHelper(WebProxy proxy)
        {
            m_proxy = proxy;
        }

        #region 实现Httprequest的Get方式提交数据,并返回数据
        /// <summary>
        /// 实现Httprequest的Get方式提交数据,并返回数据
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="timeout">超时时间</param>
        /// <returns>返回获取到的html/text/json</returns>
        public string HttpRequestGet(string url, int timeout = 300000)
        {
            string result = string.Empty;
            hwr = CreateHttpWebRequest(url, "GET");

            if (!RequestEncoding.Keys.Contains(url))
            {
                defaultEncoding = Encoding.Default;
            }
            else
            {
                defaultEncoding = RequestEncoding[url];
            }

            hwr.Timeout = timeout;
            hwr.ReadWriteTimeout = timeout;
            try
            {
                using (WebResponse wr = hwr.GetResponse())
                {
                    Stream s = wr.GetResponseStream();
                    StreamReader sr = new StreamReader(s, defaultEncoding);
                    result = sr.ReadToEnd();
                }

                if (!RequestEncoding.Keys.Contains(url))
                {   //charset=utf-8
                    Regex reg_charset = new Regex(@"charset=(?<charset>[^""|^''|^]*)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
                    if (reg_charset.IsMatch(result))
                    {
                        defaultEncoding = Encoding.GetEncoding(reg_charset.Match(result).Groups["charset"].Value);
                        RequestEncoding.Add(url, defaultEncoding);

                        hwr = CreateHttpWebRequest(url, "GET");
                        using (WebResponse wr = hwr.GetResponse())
                        {
                            Stream s = wr.GetResponseStream();
                            StreamReader sr = new StreamReader(s, defaultEncoding);
                            result = sr.ReadToEnd();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                new ExceptionHelper().LogException(e);
            }

            return result;
        }
        #endregion

        #region 实现Httprequest的Put方式提交数据,并返回数据
        /// <summary>
        /// 实现Httprequest的Get方式提交数据,并返回数据
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="timeout">超时时间</param>
        /// <returns>返回获取到的html/text/json</returns>
        public string HttpRequestPut(string url, int timeout = 300000)
        {
            string result = string.Empty;
            hwr = CreateHttpWebRequest(url, "PUT");
            hwr.Timeout = timeout;
            hwr.ReadWriteTimeout = timeout;
            try
            {
                using (WebResponse wr = hwr.GetResponse())
                {
                    Stream s = wr.GetResponseStream();
                    StreamReader sr = new StreamReader(s);
                    result = sr.ReadToEnd();
                }
            }
            catch (Exception e)
            {
                new ExceptionHelper().LogException(e);
            }

            return result;
        }
        #endregion

        #region 实现Httprequest的POST方式提交数据,并返回数据
        /// <summary>
        /// 实现Httprequest的Get方式提交数据,并返回数据
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="param">请求参数</param>
        /// <param name="timeout">超时时间</param>
        /// <returns>返回获取到的html/text/json</returns>
        public string HttpRequestPost(string url, string param, int timeout = 300000)
        {
            string result = string.Empty;
            hwr = CreateHttpWebRequest(url, "POST");
            hwr.Timeout = timeout;
            hwr.ReadWriteTimeout = timeout;
            try
            {
                if (!string.IsNullOrEmpty(param))
                {
                    byte[] bytes = Encoding.ASCII.GetBytes(param);
                    using (Stream reqStream = hwr.GetRequestStream())
                    {
                        reqStream.Write(bytes, 0, bytes.Length);
                    }
                }

                try
                {
                    using (WebResponse wr = hwr.GetResponse())
                    {
                        Stream s = wr.GetResponseStream();
                        StreamReader sr = new StreamReader(s);
                        result = sr.ReadToEnd();
                    }
                }
                catch (WebException ex)
                {
                    using (var responseReader = new StreamReader(ex.Response.GetResponseStream()))
                    {
                        result = responseReader.ReadToEnd();
                    }
                }
            }
            catch (Exception e)
            {
                new ExceptionHelper().LogException(e);
            }

            return result;
        }
        #endregion

        #region 构造出HttpWebRequest对象
        /// <summary>
        /// 构造出HttpWebRequest对象
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="method">请求方式</param>
        /// <returns>返回获取到的html/text/json</returns>
        public HttpWebRequest CreateHttpWebRequest(string url, string method = "GET")
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
            hwr = (HttpWebRequest)HttpWebRequest.Create(url);
            hwr.Method = method;
            //hwr.KeepAlive = false;
            if (m_proxy != null)
            {
                hwr.Proxy = m_proxy;
            }
            hwr.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
            return hwr;
        }
        #endregion

        public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {   // 总是接受    
            return true;
        } 

        #region 实现Httprequest的Put方式提交数据,并返回数据
        /// <summary>
        /// 实现Httprequest的Get方式提交数据,并返回数据
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="path">保存路径地址</param>
        /// <param name="fileName">文件名称</param>
        /// <param name="overwriting">是否覆盖已经存在的文件</param>
        /// <returns>返回获取到的文件操作系统上的文件路径</returns>
        public string HttpRequestGetPic(string url, string path, string fileName, bool overwriting = false)
        {
            if (!string.IsNullOrEmpty(url))
            {
                try
                {
                    WebClient wc = new WebClient();
                    if (string.IsNullOrEmpty(fileName))
                    {
                        string[] FileNames = url.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        fileName = System.Web.HttpRuntime.AppDomainAppPath + path + FileNames[FileNames.Length - 1];
                    }
                    else
                    {
                        fileName = System.Web.HttpRuntime.AppDomainAppPath + path + fileName;
                    }
                    if (!System.IO.Directory.Exists(System.Web.HttpRuntime.AppDomainAppPath + path))
                    {
                        System.IO.Directory.CreateDirectory(System.Web.HttpRuntime.AppDomainAppPath + path);
                    }

                    if (overwriting && File.Exists(fileName))
                    {
                        File.Delete(fileName);
                    }
                    wc.DownloadFile(url, fileName);
                }
                catch (Exception e)
                {
                    new ExceptionHelper().LogException(e);
                }
            }

            return fileName;
        }
        #endregion
    }
}
